package simulator;

import java.util.*;
import java.io.*;

public class Ram {
        /**
         * 
         * Memoria de Instrucciones
         */
	private String[] instructionMemory; 
	/**
         * Memoria de Datos
         */
        private String [] dataMemory;         
                
        /**
         * Singleton
         * SOLO EXISTE UNA MEMORIA
         */
        private static Ram instance = null;
        
	/**
         * Constructor
         */
        private Ram(){
            instructionMemory = new String[4096];
            dataMemory = new String [4096];           
        }
        
        /**
         * retorna la unica instancia posible de Ram en el sistema
         * @return
         */
        public static Ram getInstance(){
            if(instance == null){
                instance = new Ram();
                return instance;
            }else{
                return instance;
            }
        }
        /**
         * Funcion para acceder a la memoria de Instrucciones
         * @param direccion en formato String Hex 3 digitos
         * @return el valor (4 dig Hex) de la posicion en memoria
         */
        String getInstruction(String address){
            return instructionMemory[Integer.valueOf(address,16)];
        }
        
        String getInstruction(int address){
            return instructionMemory[address];
        }
        /**
         * Metodo para cargar un valor a una casilla de memoria para instrucciones
         * 
         * @param address Hex String format
         * @param value
         */
        void setInstructionField(String address,String value){
            this.instructionMemory[Integer.valueOf(address,16)]=value;
        }
        /**
         * Metodo para cargar un valor a una casilla de memoria para instrucciones
         * @param address in integer format
         * @param value
         */
        void setInstructionField(int address,String value){
            this.instructionMemory[address]=value;
        }
        
        /**
         * Funcion para acceder a la memoria de Datos
         * @param direccion en formato String Hex 3 digitos
         * @return el valor (4 dig Hex) de la posicion en memoria
         */
        String getData(String address){
            return dataMemory[Integer.valueOf(address,16)];
        }
        
        String getData(int address){
            return dataMemory[address];
        }
        /**
         * Metodo para llenar una casilla de memoria,
         * 
         * @param address in Hex String format
         * @param value of memory cel.
         */
        void setDataField(String address, String value){
            this.dataMemory[Integer.valueOf(address,16)]=value;
        }
        
        /**
         * Metodo para llenar una casilla de memoria,
         * 
         * @param address in Hex String format
         * @param value of memory cel.
         */
        String getDataOfStack(String valueOfStackPointer){
            return dataMemory[Integer.valueOf(valueOfStackPointer,16)];
        }
        
        void setStackField(String address, String value){
            this.dataMemory[Integer.valueOf(address,16)]=value;
        }
        
        
        
        
        void setDataField(int address, String value){
            this.dataMemory[address]=value;
        }
        /**
         * Funcion para acceder a la memoria de la Pila
         * @param direccion en formato String Hex 3 digitos
         * @return el valor (4 dig Hex) de la posicion en memoria
         */
        
        
        String getItAddress(int itNr){
            String result = this.getInstruction(Integer.toHexString(itNr));
            return result;
        }
        /**
         * 
         * @return
         */
        String[][] getDataTable(){            
            String[][] result = new String[256][16];
            int col = 0,row=0;
            for(int i=0;i<dataMemory.length;i++){
                if(col>15){
                    row++;
                    col=0;
                }
                result[row][col] = dataMemory[i];
            }
            return result;         
        }
}